package com.ds.app;

import com.ds.app.database.*;
import com.ds.app.inner.EIModule;
import com.ds.app.proxy.ModuleProxy;
import com.ds.app.proxy.ModuleProxyManager;
import com.ds.common.CommonConfig;
import com.ds.common.JDSException;
import com.ds.common.cache.Cache;
import com.ds.common.cache.CacheManagerFactory;
import com.ds.common.database.DBAgent;
import com.ds.common.logging.Log;
import com.ds.common.logging.LogFactory;
import com.ds.org.OrgManager;
import com.ds.org.Role;
import com.ds.org.RoleNotFoundException;
import com.ds.org.conf.OrgConfig;
import com.ds.org.conf.OrgConstants;
import com.ds.org.conf.Query;
import com.ds.org.conf.Query.ColumnMapping;
import com.ds.org.conf.Query.SqlClause;
import com.ds.server.OrgManagerFactory;
import com.ds.server.SubSystem;
import com.ds.server.eumus.ConfigCode;

import java.io.Serializable;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;

/**
 * <p>
 * Title: JDSORG组织机构中间件
 * </p>
 * <p>
 * Description:
 * </p>
 * <p>
 * Copyright: jds Copyright (c) 2003-2008
 * </p>
 * <p>
 * Company: www.justdos.net
 * </p>
 *
 * @author wenzhangli
 * @version 2.0
 */
public class AppCacheManager implements Serializable {
    private static ConfigCode configKey = OrgConstants.CONFIG_KEY;
    protected static Log log = LogFactory.getLog(configKey.getType(), AppCacheManager.class);
    private static Map<ConfigCode, AppCacheManager> CacheManagerMap = new HashMap<ConfigCode, AppCacheManager>();
    private OrgConfig config;

    // name caches

    private Cache<String, App> appCache;

    private Cache<String, String> appNameCache;

    private Cache<String, DbModuleProperty> modulePrivateProcertyCache;
    private Cache<String, DbModuleProperty> modulePublicProcertyCache;

    private Cache<String, Module> moduleProxyCache;
    private Cache<String, DbPersonModuleProperty> personModulePrivateProcertyCache;
    private Cache<String, DbPersonModuleProperty> personModulePublicProcertyCache;

    private Cache<String, DbDeskTopProperty> deskTopPropertyCache;
    private boolean cacheEnabled;

    // 动态属性

    private ConfigCode configCode;
    // private List<Folder> topFolders;

    private OrgManager orgManager;
    private DBAppDataBaseManager appManager;

    private static boolean orgInit = false;

    private List<String> topAppIds = new ArrayList<String>();
    private ModuleProxyManager moduleManager;

    private static final String ORGID = "org";

    private void init() {
        String enabled = CommonConfig.getValue(OrgConstants.CONFIG_KEY.getType() + ".cache.enabled");
        cacheEnabled = Boolean.valueOf(enabled).booleanValue();
        initCache();
        if (cacheEnabled) {
            try {
                loadData();
            } catch (Exception e) {
                e.printStackTrace();
            }

            long interval = 3600000; // 1小时
            String lifeTime = CommonConfig.getValue(configCode + ".cache.lifeTime");
            try {
                interval = Long.parseLong(lifeTime);
            } catch (Exception e) {
            }
            // 定时更新cache(除person, org外)
            // TaskEngine.scheduleTask(new ReloadCacheTask(), interval, interval);
        }
    }

    /**
     * Creates a new cache manager.
     */
    AppCacheManager(ConfigCode configCode) {
        this.config = OrgConfig.getInstance(configCode);
        this.configCode = configCode;
        this.orgManager = OrgManagerFactory.getOrgManager(configCode);
        this.appManager = DBAppDataBaseManager.getInstance(configCode);
        this.moduleManager = ModuleProxyManager.getInstance(configCode);

    }

    public static AppCacheManager getInstance(ConfigCode configCode) {
        if (configCode == null) {
            configCode = OrgConstants.CONFIG_KEY;
        }
        AppCacheManager cacheManager = CacheManagerMap.get(configCode);
        if (cacheManager == null) {
            cacheManager = new AppCacheManager(configCode);
            CacheManagerMap.put(configCode, cacheManager);
            cacheManager.init();
        }
        return cacheManager;
    }

    /**
     * Initializes all caches with the correct size and expiration time.
     */
    private void initCache() {
        // Initialize all caches, turn expire flag off
        // 最好是orgCache与personCache足够大，或者不限制大小，否则会比较影响效率，反而浪费内存

        if (config.isSupportApp()) {
            appCache = CacheManagerFactory.createCache(configCode.getType(), "app", -1, 0);
            appNameCache = CacheManagerFactory.createCache(configCode.getType(), "appName", -1, 0);
        }
        if (config.isSupportModule()) {
            moduleProxyCache = CacheManagerFactory.createCache(configCode.getType(), "moduleProxy", -1, 0);
        }

        if (config.isSupportModuleProperty()) {

            this.modulePrivateProcertyCache = CacheManagerFactory.createCache(configCode.getType(), "modulePrivateProcerty", -1, 0);
            this.modulePublicProcertyCache = CacheManagerFactory.createCache(configCode.getType(), "modulePublicProcerty", -1, 0);

        }

        if (config.isSupportPersonModuleProperty()) {
            this.personModulePrivateProcertyCache = CacheManagerFactory.createCache(configCode.getType(), "personModulePrivateProcertyCache", -1, 0);
            this.personModulePublicProcertyCache = CacheManagerFactory.createCache(configCode.getType(), "personModulePublicProcertyCache", -1, 0);
        }

        if (config.isSupportDeskTopProperty()) {
            this.deskTopPropertyCache = CacheManagerFactory.createCache(configCode.getType(), "deskTopProperty", -1, 0);

        }

    }

    // 从数据库中加载数据
    private void loadData() {
        long start = System.currentTimeMillis();
        DBAgent db = null;
        if (!this.orgInit) {
            try {
                db = new DBAgent(ORGID);
                log.info(this.configCode + " loadData start ");

                if (config.isSupportModuleProperty()) {
                    this.loadModulePropertits(db);
                }
                if (config.isSupportPersonModuleProperty()) {
                    this.loadPersonModulePropertits(db);
                }
                if (config.isSupportDeskTopProperty()) {
                    this.loadDeskTopProperty(db);
                }

            } catch (SQLException e) {
                e.printStackTrace();
            } catch (JDSException e) {
                e.printStackTrace();
            } finally {
                if (db != null) {
                    db.close();
                }


                orgInit = true;
            }


        }

        try {
            db = new DBAgent(configCode.getType());

            if (config.isSupportModule()) {
                loadApps(db);
                loadModuleApp(db);
                // 载入模块与应用的关联
                loadModuleRelavant(db);
            }

            if (config.isSupportApp()) {
                loadAppRelavant(db);
            }

            // 设置Org与Person的初始化标记
            setInitalizedFlag();
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (JDSException e) {
            e.printStackTrace();
        } finally {
            if (db != null) {
                db.close();
            }
        }


        log.info(this.configCode + " tooks " + (System.currentTimeMillis() - start));
    }

    /**
     * 设置Org与Person的初始化标记
     */
    private void setInitalizedFlag() {

    }

    private void loadApps(DBAgent db) {
        ResultSet rs = null;
        SqlClause sqlClause;
        String strSql;
        Map columnMap;

        if (config.getQuery("App") == null) {
            return;
        }

        // 全部应用信息
        sqlClause = config.getQuery("App").getSqlClause("basic");
        columnMap = sqlClause.getColumnMappings();
        strSql = buildSql(sqlClause);
        if (db.execute(strSql) == 1) {
            // 清空后再加
            appCache.clear();
            rs = db.getQueryResult();
            try {
                while (rs.next()) {
                    DbApp app = appManager.decodeRow(rs, true);
                    appCache.put(app.getID(), app);
                }
                rs.close();
            } catch (SQLException ex) {
                log.error("", ex);
                return;
            }
        }
    }

    /**
     * 载入模块与应用的关联
     *
     * @param db
     */
    private void loadModuleApp(DBAgent db) {
        ResultSet rs = null;
        SqlClause sqlClause;
        String strSql;
        Map columnMap;
        // 2.模块应用

        if (config.getQuery("Module-App") == null) {
            return;
        }
        sqlClause = config.getQuery("Module-App").getSqlClause("basic");
        if (sqlClause != null) {
            columnMap = sqlClause.getColumnMappings();
            strSql = buildSql(sqlClause);
            if (db.execute(strSql) == 1) {
                rs = db.getQueryResult();
                try {
                    while (rs.next()) {
                        String moduleId = getString(rs, columnMap.get("moduleId"));
                        String appId = getString(rs, columnMap.get("appId"));
                        ModuleProxy module = (ModuleProxy) this.getModuleByID(moduleId);
                        DbApp app = (DbApp) appCache.get(appId);
                        // 为模块增加应用
                        if (module != null) {
                            module.addApp(appId);
                        }
                        // 为应用增加模块
                        if (app != null) {
                            app.addModule(moduleId);
                        }
                    }
                } catch (Exception ex1) {
                    log.error("", ex1);
                    return;
                }
            }
        }
    }

    /**
     * 载入模块与其他的关联表
     *
     * @param db
     */
    private void loadModuleRelavant(DBAgent db) {
        ResultSet rs = null;
        SqlClause sqlClause;
        String strSql;
        Map columnMap;
        // 1.模块角色

        if (config.isSupportPersonRole() && config.getQuery("Module-PersonRole") != null) {
            Query query = config.getQuery("Module-PersonRole");
            if (query != null) {
                sqlClause = query.getSqlClause("basic");
                if (sqlClause != null) {
                    columnMap = sqlClause.getColumnMappings();
                    strSql = buildSql(sqlClause);
                    if (db.execute(strSql) == 1) {
                        rs = db.getQueryResult();
                        try {
                            while (rs.next()) {
                                String moduleId = getString(rs, columnMap.get("moduleId"));
                                String personRoleId = getString(rs, columnMap.get("personRoleId"));
                                ModuleProxy module = null;
                                Role role = null;
                                try {
                                    module = (ModuleProxy) this.getModuleByID(moduleId);
                                    role = (Role) orgManager.getRoleByID(personRoleId);
                                } catch (ModuleNotFoundException e) {
                                    log.error("", e);
                                } catch (RoleNotFoundException e) {
                                    log.error("", e);
                                }
                                if (module != null && role != null) {
                                    // 为模块增加角色
                                    module.addRole(personRoleId);

                                }

                            }
                        } catch (SQLException ex2) {
                            log.error("", ex2);
                            return;
                        }
                    }
                }
            } // end of if(query != null)
        }

    }

    /**
     * 载入应用与其他的关联表
     *
     * @param db
     */
    private void loadAppRelavant(DBAgent db) {
        ResultSet rs = null;
        SqlClause sqlClause;
        String strSql;
        Map columnMap;

        // 1.应用角色
        if (config.isSupportPersonRole() && config.getQuery("App-PersonRole") != null) {
            Query query = config.getQuery("App-PersonRole");
            if (query != null) {
                sqlClause = query.getSqlClause("basic");
                if (sqlClause != null) {
                    columnMap = sqlClause.getColumnMappings();
                    strSql = buildSql(sqlClause);
                    if (db.execute(strSql) == 1) {
                        rs = db.getQueryResult();
                        try {
                            while (rs.next()) {
                                String appId = getString(rs, columnMap.get("appId"));
                                String personRoleId = getString(rs, columnMap.get("personRoleId"));
                                DbApp app = (DbApp) this.getAppByID(appId);
                                Role role = orgManager.getPersonRoleByID(personRoleId);
                                // 为应用增加角色
                                if (app != null) {
                                    app.addRole(personRoleId);
                                }

                            }
                        } catch (Exception ex2) {
                            log.error("", ex2);
                            return;
                        }
                    }
                }
            } // end of if(query != null)
        }

    }

    private void loadPersonModulePropertits(DBAgent db) {
        ResultSet rs = null;
        SqlClause sqlClause;
        String strSql;
        Map columnMap;
        // 缓存全部模块的配置信息
        if (config.getQuery("PersonModuleProperty") == null) {
            return;
        }
        sqlClause = config.getQuery("PersonModuleProperty").getSqlClause("basic");
        columnMap = sqlClause.getColumnMappings();
        strSql = buildSql(sqlClause);
        if (db.execute(strSql) == 1) {
            this.modulePrivateProcertyCache.clear();
            this.modulePublicProcertyCache.clear();
            rs = db.getQueryResult();
            try {
                while (rs.next()) {
                    String ID = getString(rs, columnMap.get("ID"));
                    String moduleId = getString(rs, columnMap.get("moduleId"));
                    String path = getString(rs, columnMap.get("path"));
                    int index = getInt(rs, columnMap.get("index"));
                    int moduleStatus = getInt(rs, columnMap.get("moduleStatus"));

                    String personId = getString(rs, columnMap.get("personId"));
                    String exprocession = getString(rs, columnMap.get("exprocession"));
                    String type = getString(rs, columnMap.get("type"));
                    String winConfig = getString(rs, columnMap.get("winConfig"));
                    String url = getString(rs, columnMap.get("url"));
                    String childModule = getString(rs, columnMap.get("childModule"));
                    String cls = getString(rs, columnMap.get("cls"));
                    String icon = getString(rs, columnMap.get("icon"));
                    String thumb = getString(rs, columnMap.get("thumb"));
                    Date creatTime = getDate(rs, columnMap.get("creatTime"));
                    Date lastModified = getDate(rs, columnMap.get("lastModified"));
                    DbPersonModuleProperty moduleProperty = new DbPersonModuleProperty(this.configCode);
                    moduleProperty.setChildModule(childModule);
                    moduleProperty.setID(ID);
                    moduleProperty.setIndex(index);
                    moduleProperty.setModuleStatus(moduleStatus);
                    moduleProperty.setPath(path);
                    moduleProperty.setModuleId(moduleId);
                    moduleProperty.setExprocession(exprocession);
                    moduleProperty.setPersonId(personId);
                    moduleProperty.setUrl(url);
                    moduleProperty.setType(type);
                    moduleProperty.setWinConfig(winConfig);
                    moduleProperty.setCls(cls);
                    moduleProperty.setIcon(icon);
                    moduleProperty.setThumb(thumb);
                    moduleProperty.setCreatTime(creatTime);
                    moduleProperty.setLastModified(lastModified);
                    // put into cache
                    personModulePrivateProcertyCache.put(ID, moduleProperty);
                    if (personId.equals("public")) {
                        personModulePublicProcertyCache.put(moduleId, moduleProperty);
                    }
                }
                rs.close();
            } catch (SQLException ex) {
                log.error("", ex);
            }
        }
    }

    private void loadModulePropertits(DBAgent db) {
        ResultSet rs = null;
        SqlClause sqlClause;
        String strSql;
        Map columnMap;
        // 缓存全部模块的配置信息
        if (config.getQuery("ModuleProperty") == null) {
            return;
        }
        sqlClause = config.getQuery("ModuleProperty").getSqlClause("basic");
        columnMap = sqlClause.getColumnMappings();
        strSql = buildSql(sqlClause);

        if (db.execute(strSql) == 1) {
            this.modulePrivateProcertyCache.clear();
            this.modulePublicProcertyCache.clear();
            rs = db.getQueryResult();
            try {
                while (rs.next()) {
                    String ID = getString(rs, columnMap.get("ID"));
                    String moduleId = getString(rs, columnMap.get("moduleId"));
                    String personId = getString(rs, columnMap.get("personId"));
                    int height = getInt(rs, columnMap.get("height"));
                    int width = getInt(rs, columnMap.get("width"));
                    int x = getInt(rs, columnMap.get("x"));
                    int y = getInt(rs, columnMap.get("y"));

                    DbModuleProperty moduleProperty = new DbModuleProperty(this.configCode);

                    moduleProperty.setID(ID);
                    moduleProperty.setModuleId(moduleId);

                    moduleProperty.setPersonId(personId);
                    moduleProperty.setX(x);
                    moduleProperty.setY(y);
                    moduleProperty.setHeight(height);
                    moduleProperty.setWidth(width);
                    // put into cache
                    modulePrivateProcertyCache.put(ID, moduleProperty);
                    if (personId.equals("public")) {
                        modulePublicProcertyCache.put(moduleId, moduleProperty);
                    }
                }
                rs.close();
            } catch (SQLException ex) {
                log.error("", ex);
            }
        }
    }

    private void loadDeskTopProperty(DBAgent db) {
        ResultSet rs = null;
        SqlClause sqlClause;
        String strSql;
        Map columnMap;
        // 缓存全部模块的配置信息
        if (config.getQuery("DeskTopProperty") == null) {
            return;
        }
        sqlClause = config.getQuery("DeskTopProperty").getSqlClause("basic");
        columnMap = sqlClause.getColumnMappings();
        strSql = buildSql(sqlClause);

        if (db.execute(strSql) == 1) {
            this.deskTopPropertyCache.clear();
            rs = db.getQueryResult();
            try {
                while (rs.next()) {
                    String personId = getString(rs, columnMap.get("personId"));
                    String backGroundColor = getString(rs, columnMap.get("backGroundColor"));
                    String fontColor = getString(rs, columnMap.get("fontColor"));

                    String themeId = getString(rs, columnMap.get("themeId"));
                    String wallPaperId = getString(rs, columnMap.get("wallPaperId"));

                    String shortcut = getString(rs, columnMap.get("shortcut"));
                    String autorun = getString(rs, columnMap.get("autorun"));
                    String quickStart = getString(rs, columnMap.get("quickStart"));
                    String openerwin = getString(rs, columnMap.get("openerwin"));
                    String wallParperPosition = getString(rs, columnMap.get("wallPaperPosition"));

                    DbDeskTopProperty dbDeskTopProperty = new DbDeskTopProperty(this.configCode);
                    dbDeskTopProperty.setPersonId(personId);
                    dbDeskTopProperty.setAutorun(autorun);
                    dbDeskTopProperty.setFontColor(fontColor);
                    dbDeskTopProperty.setShortcut(shortcut);
                    dbDeskTopProperty.setBackGroundColor(backGroundColor);
                    dbDeskTopProperty.setThemeId(themeId);
                    dbDeskTopProperty.setWallPaperId(wallPaperId);
                    dbDeskTopProperty.setOpenerwin(openerwin);
                    dbDeskTopProperty.setQuickStart(quickStart);
                    if (columnMap.get("macbar") != null && !columnMap.get("macbar").equals("")) {
                        dbDeskTopProperty.setMacbar(getString(rs, columnMap.get("macbar")));
                    }
                    if (columnMap.get("macshortcut") != null && !columnMap.get("macshortcut").equals("")) {
                        dbDeskTopProperty.setMacshortcut(getString(rs, columnMap.get("macshortcut")));
                    }
                    if (columnMap.get("rightbar") != null && !columnMap.get("rightbar").equals("")) {
                        dbDeskTopProperty.setRightbar(getString(rs, columnMap.get("rightbar")));
                    }

                    dbDeskTopProperty.setWallPaperPosition(wallParperPosition);
                    deskTopPropertyCache.put(personId, dbDeskTopProperty);

                }
                rs.close();
            } catch (SQLException ex) {
                log.error("", ex);
            }
        }
    }

    public Module getModuleByID(String moduleId) throws ModuleNotFoundException {
        if (!cacheEnabled) {
            DbModule module = (DbModule) AppRoManager.getInstance().getModuleByID(moduleId);

            return moduleManager.loadModuleByKey(module);
        }
        // Cache is enabled.
        Module module = (ModuleProxy) moduleProxyCache.get(moduleId);
        if (module == null) {
            EIModule dbmodule = (DbModule) AppRoManager.getInstance().getModuleByID(moduleId);
            module = moduleManager.loadModuleByKey(dbmodule);
            moduleProxyCache.put(moduleId, module);

        }
        return module;
    }

    public Module getModuleByServiceID(String serviceId) throws ModuleNotFoundException {
        DbModule dbmodule = (DbModule) AppRoManager.getInstance().getModuleByServiceID(serviceId);
        if (!cacheEnabled) {
            return moduleManager.loadModuleByKey(dbmodule);
        }
        // Cache is enabled.
        Module module = (ModuleProxy) moduleProxyCache.get(dbmodule.getID());
        if (module == null) {
            module = moduleManager.loadModuleByKey(dbmodule);
            moduleProxyCache.put(dbmodule.getID(), module);

        }
        return module;
    }

    public void removeModule(String moduleId) {
        if (moduleProxyCache.containsKey(moduleId)) {
            synchronized (moduleId) {
                moduleProxyCache.remove(moduleId);
            }
        }
    }

    public DbDeskTopProperty getDeskTopPropertyByID(String personId) throws DeskTopPropertyNotFoundException {
        if (!cacheEnabled) {
            return new DbDeskTopProperty(personId, this.configCode);
        }
        // Cache is enabled.
        DbDeskTopProperty dbDeskTopProperty = (DbDeskTopProperty) deskTopPropertyCache.get(personId);
        if (dbDeskTopProperty == null) {
            dbDeskTopProperty = new DbDeskTopProperty(personId, this.configCode);

            deskTopPropertyCache.put(personId, dbDeskTopProperty);
        }
        return dbDeskTopProperty;
    }

    public DbPersonModuleProperty getPersonModulePropertyByID(String modulePropertyId, String personId) throws ModuleNotFoundException {
        if (!cacheEnabled) {
            return new DbPersonModuleProperty(modulePropertyId, this.configCode);
        }
        // Cache is enabled.
        DbPersonModuleProperty moduleProperty = (DbPersonModuleProperty) personModulePrivateProcertyCache.get(modulePropertyId);

        if (moduleProperty == null) {
            moduleProperty = (DbPersonModuleProperty) personModulePublicProcertyCache.get(modulePropertyId);
            if (moduleProperty == null) {
                moduleProperty = new DbPersonModuleProperty(modulePropertyId, this.configCode, personId);
                personModulePrivateProcertyCache.put(modulePropertyId, moduleProperty);
            }
        }
        return moduleProperty;
    }

    public DbModuleProperty getModulePropertyByID(String modulePropertyId) throws ModuleNotFoundException {
        if (!cacheEnabled) {
            return new DbModuleProperty(modulePropertyId, this.configCode);
        }
        // Cache is enabled.
        DbModuleProperty moduleProperty = (DbModuleProperty) modulePrivateProcertyCache.get(modulePropertyId);
        if (moduleProperty == null) {
            moduleProperty = new DbModuleProperty(modulePropertyId, this.configCode);
            modulePrivateProcertyCache.put(modulePropertyId, moduleProperty);
        }

        return moduleProperty;
    }

    public DbModuleProperty getModulePropertyByModuleId(String moduleId) throws ModuleNotFoundException {
        if (!cacheEnabled) {
            return new DbModuleProperty(moduleId, this.configCode);
        }
        // Cache is enabled.
        DbModuleProperty moduleProperty = (DbModuleProperty) modulePublicProcertyCache.get(moduleId);
        if (moduleProperty == null) {
            moduleProperty = new DbModuleProperty(moduleId, this.configCode, null);
            modulePublicProcertyCache.put(moduleId, moduleProperty);
        }

        return moduleProperty;
    }

    public App getAppByID(String appId) throws AppNotFoundException {
        if (!cacheEnabled) {
            return appManager.loadAppByKey(appId);
        }
        // Cache is enabled.
        App app = (App) appCache.get(appId);
        if (app == null) {
            app = appManager.loadAppByKey(appId);
            appCache.put(appId, app);
        }
        return app;
    }

    public void removeApp(String appId) {
        if (appCache.containsKey(appId)) {
            synchronized (appId) {
                appCache.remove(appId);
            }
        }
    }

    private String buildSql(SqlClause sqlClause) {
        String strSql = sqlClause.getMainClause();
        String strWhere = sqlClause.getWhereClause();
        String strOrder = sqlClause.getOrderClause();
        if (strWhere != null && !strWhere.equals("")) {
            strSql = strSql + " " + strWhere;
        }
        if (strOrder != null && !strOrder.equals("")) {
            strSql = strSql + " " + strOrder;
        }
        return strSql;
    }

    private String getString(ResultSet rs, Object column) {
        if (column != null) {
            try {
                return rs.getString(((ColumnMapping) column).getColumnAlias());
            } catch (SQLException ex) {
                return null;
            }
        }
        return null;
    }

    private Date getDate(ResultSet rs, Object column) {
        if (column != null) {
            try {
                return rs.getDate(((ColumnMapping) column).getColumnAlias());
            } catch (SQLException ex) {
                return null;
            }
        }
        return null;
    }

    private Integer getInt(ResultSet rs, Object column) {
        if (column != null && !column.toString().equals("")) {
            try {
                return rs.getInt(((ColumnMapping) column).getColumnAlias());
            } catch (SQLException ex) {
                return null;
            }
        }
        return 0;
    }

    public void reloadAll() {
        this.loadData();
    }

    public void reloadCache() {
        DBAgent db = null;
        try {
            db = new DBAgent(configKey.getType());
            loadApps(db);
            loadModuleRelavant(db);
            loadAppRelavant(db);
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (JDSException e) {
            e.printStackTrace();
        } finally {
            if (db != null) {
                db.close();
            }
        }


    }

    /**
     * 动态加载Cache（Org与Person除外）。
     */
    private class ReloadCacheTask implements Runnable {
        public void run() {
            reloadCache();
        }
    }

    private Double getDouble(ResultSet rs, Object column) {
        if (column != null && !column.toString().equals("")) {
            try {
                return rs.getDouble(((ColumnMapping) column).getColumnAlias());
            } catch (SQLException ex) {
                return null;
            }
        }
        return null;
    }

    public Cache getAppCache() {
        if (appCache == null || appCache.isEmpty()) {
            DBAgent db = null;
            try {
                db = new DBAgent(this.configCode.getType());
                this.loadAppRelavant(db);
                this.loadApps(db);
                ;
            } catch (SQLException e) {
                e.printStackTrace();
            } catch (JDSException e) {
                e.printStackTrace();
            } finally {
                if (db != null) {
                    db.close();
                }
            }
        }
        return appCache;
    }

    public Cache getAppNameCache() {
        if (appNameCache == null || appNameCache.isEmpty()) {
            DBAgent db = null;
            try {
                db = new DBAgent(this.configCode.getType());
                this.loadAppRelavant(db);
                this.loadApps(db);
            } catch (SQLException e) {
                e.printStackTrace();
            } catch (JDSException e) {
                e.printStackTrace();
            } finally {
                if (db != null) {
                    db.close();
                }
            }
        }
        return appNameCache;
    }

    public void setAppNameCache(Cache appNameCache) {
        this.appNameCache = appNameCache;
    }

    public boolean isCacheEnabled() {
        return cacheEnabled;
    }

    public void setCacheEnabled(boolean cacheEnabled) {
        this.cacheEnabled = cacheEnabled;
    }

    public Cache getDeskTopPropertyCache() {
        if (deskTopPropertyCache == null || deskTopPropertyCache.isEmpty()) {
            DBAgent db = null;
            try {
                db = new DBAgent(this.configCode.getType());
                this.loadModulePropertits(db);
            } catch (SQLException e) {
                e.printStackTrace();
            } catch (JDSException e) {
                e.printStackTrace();
            } finally {
                if (db != null) {
                    db.close();
                }
            }
        }
        return deskTopPropertyCache;
    }

    public Cache getModulePrivateProcertyCache() {
        if (modulePrivateProcertyCache == null || modulePrivateProcertyCache.isEmpty()) {
            DBAgent db = null;
            try {
                db = new DBAgent(this.configCode.getType());
                this.loadPersonModulePropertits(db);
            } catch (SQLException e) {
                e.printStackTrace();
            } catch (JDSException e) {
                e.printStackTrace();
            } finally {
                if (db != null) {
                    db.close();
                }
            }
        }
        return modulePrivateProcertyCache;
    }

    public Cache getModulePublicProcertyCache() {
        if (modulePublicProcertyCache == null || modulePublicProcertyCache.isEmpty()) {

            DBAgent db = null;
            try {
                db = new DBAgent(this.configCode.getType());
                loadApps(db);
                loadModuleApp(db);
                // 载入模块与应用的关联
                loadModuleRelavant(db);
            } catch (SQLException e) {
                e.printStackTrace();
            } catch (JDSException e) {
                e.printStackTrace();
            } finally {
                if (db != null) {
                    db.close();
                }
            }

        }
        return modulePublicProcertyCache;
    }

    public Cache getPersonModulePrivateProcertyCache() {
        if (personModulePrivateProcertyCache == null || personModulePrivateProcertyCache.isEmpty()) {
            DBAgent db = null;
            try {
                db = new DBAgent(this.configCode.getType());
                this.loadPersonModulePropertits(db);
            } catch (SQLException e) {
                e.printStackTrace();
            } catch (JDSException e) {
                e.printStackTrace();
            } finally {
                if (db != null) {
                    db.close();
                }
            }
        }
        return personModulePrivateProcertyCache;
    }

    public Cache getPersonModulePublicProcertyCache() {
        if (personModulePublicProcertyCache == null || personModulePublicProcertyCache.isEmpty()) {
            DBAgent db = null;
            try {
                db = new DBAgent(this.configCode.getType());
                this.loadPersonModulePropertits(db);
            } catch (SQLException e) {
                e.printStackTrace();
            } catch (JDSException e) {
                e.printStackTrace();

            } finally {
                if (db != null) {
                    db.close();
                }
            }
        }
        return personModulePublicProcertyCache;
    }

    public List<App> getTopApps() {

        OrgConfig config = OrgConfig.getInstance(configCode);
        SqlClause sqlClause = config.getQuery("App").getSqlClause("top");
        ;
        List<App> appList = new ArrayList();
        if (sqlClause.getTopIds() != null && !sqlClause.getTopIds().equals("")) {
            String[] topIds = sqlClause.getTopIds().split(";");
            for (int k = 0; k < topIds.length; k++) {
                topAppIds.add(topIds[k]);
            }
        } else {

            DBAgent db = null;
            ResultSet rs = null;
            String strSql;
            Map columnMap;

            // 1.基本属性
            try {
                sqlClause = config.getQuery("App").getSqlClause("top");
                columnMap = sqlClause.getColumnMappings();
                strSql = buildSql(sqlClause);
                db = new DBAgent(this.configCode.getType());
                if (db.execute(strSql) == 1) {
                    rs = db.getQueryResult();
                    while (rs.next()) {
                        String appId = getString(rs, columnMap.get("appId"));
                        topAppIds.add(appId);
                    }
                }
            } catch (SQLException e) {
                return new ArrayList<App>();
            } catch (JDSException e) {
                e.printStackTrace();
            } finally {
                if (db != null) {
                    db.close();
                }

            }
        }
        for (int k = 0; k < topAppIds.size(); k++) {
            try {
                appList.add(this.getAppByID(topAppIds.get(k)));
            } catch (AppNotFoundException e) {
                e.printStackTrace();
            }
        }
        if (appList.size() == 0) {
            DbApp app = appManager.creatApp();
            SubSystem system = OrgManagerFactory.getInstance().getSystemMap().get(configCode.getType());
            app.setID(UUID.randomUUID().toString());
            app.setName(system.getName());
            app.setSubSystemId(configCode);
            app.setParentId("00000000-0000-0000-0000-000000000000");
            appManager.insert(app);
            appList.add(app);
        }

        return appList;

    }

    public List getAppList() {
        DBAgent db = null;
        OrgConfig config = OrgConfig.getInstance(configCode);
        ResultSet rs = null;
        SqlClause sqlClause;
        String strSql;
        Map columnMap;
        List<App> appList = new ArrayList<App>();
        Map<String, App> appMap = new HashMap<String, App>();

        // 1.基本属性
        try {
            sqlClause = config.getQuery("App").getSqlClause("basic");
            columnMap = sqlClause.getColumnMappings();
            strSql = buildSql(sqlClause);
            db = new DBAgent(this.configCode.getType());
            if (db.execute(strSql) == 1) {
                rs = db.getQueryResult();
                while (rs.next()) {
                    DbApp app = this.appManager.decodeRow(rs, true);
                    appList.add(app);
                    appMap.put(app.getID(), app);
                }
            }

            // 2.模块信息
            sqlClause = config.getQuery("Module-App").getSqlClause("basic");
            if (sqlClause != null) {
                columnMap = sqlClause.getColumnMappings();
                strSql = buildSql(sqlClause);
                if (db.execute(strSql) == 1) {
                    rs = db.getQueryResult();
                    while (rs.next()) {
                        DbApp app = (DbApp) appMap.get(getString(rs, columnMap.get("appId")));
                        if (app != null) {
                            app.addChild(getString(rs, columnMap.get("moduleId")));
                        }
                    }
                }
            }
        } catch (SQLException e) {
            return new ArrayList<App>();
        } catch (JDSException e) {
            e.printStackTrace();
        } finally {
            if (db != null) {
                db.close();
            }
        }

        // 设置初始化标记。
        for (int i = 0; i < appList.size(); i++) {
            ((DbApp) appList.get(i)).moduleIdList_is_initialized = true;
        }
        return appList;
    }

    public List<String> getModuleIdList() {

        List moduleIdList = new ArrayList<String>();
        DBAgent db = null;
        OrgConfig config = OrgConfig.getInstance(configCode);
        ResultSet rs = null;
        SqlClause sqlClause;
        String strSql;
        Map columnMap;
        // 1.基本属性
        try {
            sqlClause = config.getQuery("Module").getSqlClause("basic");
            columnMap = sqlClause.getColumnMappings();
            strSql = buildSql(sqlClause);
            db = new DBAgent(this.configCode.getType());
            if (db.execute(strSql) == 1) {
                rs = db.getQueryResult();
                while (rs.next()) {
                    String moduleId = getString(rs, columnMap.get("moduleId"));
                    moduleIdList.add(moduleId);
                }
            }
        } catch (SQLException e) {
            e.printStackTrace();
            return new ArrayList<String>();
        } catch (JDSException e) {
            e.printStackTrace();
        } finally {
            if (db != null) {
                db.close();
            }
        }

        return moduleIdList;
    }


}
